#pragma once
//============================================================================
// Copyright (C) 2009-2013 Brett R. Jones
// All Rights Reserved
//
// You may redistribute and/or modify for non commercial and commercial uses
// provided this copyright notice remains in place and is not modified
//
// This code is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================

#include <string>
#include <vector>
#include <VxUtilLib/VxFileLists.h>
#include <RcWebServerLib/RcWebSkt.h>
#include <VxNetLib/VxSktBaseMgr.h>
#include "RcWebPageSettings.h"

class RcPluginWebServer;

//HTTP ERRORS
//
// These numbers relate to their
// sequence in an array in
//
#define HTTP_STATUS_OK				0
#define HTTP_STATUS_CREATED			1
#define HTTP_STATUS_ACCEPTED		2
#define HTTP_STATUS_NOCONTENT		3
#define HTTP_STATUS_MOVEDPERM		4
#define HTTP_STATUS_MOVEDTEMP		5
#define HTTP_STATUS_NOTMODIFIED		6
#define HTTP_STATUS_BADREQUEST		7
#define HTTP_STATUS_UNAUTHORIZED	8
#define HTTP_STATUS_FORBIDDEN		9
#define HTTP_STATUS_NOTFOUND		10
#define HTTP_STATUS_SERVERERROR		11
#define HTTP_STATUS_NOTIMPLEMENTED	12
#define HTTP_STATUS_BADGATEWAY		13
#define HTTP_STATUS_UNAVAILABLE		14

////============================================================================
////! send standard http error to browser
//RCODE SendHttpErr( RcWebSkt * poSkt, int iErrIdx );
////============================================================================

class VxWbSharedFiles
{
public:
	//=== constructor ===//
	VxWbSharedFiles(){};

	//=== vars ===//
	std::vector<VxFileInfo>	m_aoFiles;
};

class VxWbAllFiles
{
public:
	//=== constructor ===//
	VxWbAllFiles(){};

	//=== vars ===//
	VxWbSharedFiles		m_aoSharedFiles[ eMaxAllWbMyFiles ];

};

class VxPwdEntry
{
public:
	//=== constructor ===//
	VxPwdEntry()
		: m_iPwdAttempts(0)
	{
		// empty
	}

	//=== vars ===//
	int				m_iPwdAttempts;			// failed pwd attempts count
	std::string		m_strPwd;				// if pwd success.. this is the pwd
};

class VxSharedFilesAuth
{
public:
	//=== constructor ===//
	VxSharedFilesAuth()
		: m_u32Ip(0)
		, m_u64LastAttemptTime(0)
	{
		// empty
	}

	//=== vars ===//
	U32				m_u32Ip;							// ip address of remote user				
	U64				m_u64LastAttemptTime;				// time last attempt was made ( successfull or not )
	VxPwdEntry		m_aoPwds[ eMaxNormalWbMyFiles ];	// password attempts etc
};

class RcWebServer : public VxSktBaseMgr, public VxWbAllFiles, public RcWebPageSettings
{
public:
	//=== vars ===//
	RcPluginWebServer *					m_poWebPlugin;
	bool								m_bWebServerEnabled;
	bool								m_bShuttingDown;
	#ifdef USE_WEB_FILESHARE
		std::vector<VxSharedFilesAuth>		m_aoAuthorizations;
	#endif // USE_WEB_FILESHARE

	//=== constructor ===//
	RcWebServer();
	//=== destructor ===//
	virtual ~RcWebServer();

	//=== helpers ===//
	void			setPluginWebServer( RcPluginWebServer * poPlugin );

	//! set root directory of web site
	void			setWebSiteDir( const char * pWebSiteDir );
	//! get root directory of web site
	std::string&	getWebSiteDir(  void );

	//! set enable
	void			SetWebServerEnable( bool bEnable );

	//=== overrides ===//
	//! handle callbacks from sockets
	void			DoRecieveCallback( VxSktBase * poSkt );

	//=== methods ===//
	// shutdown web server
	void	webServerShutdown( void );

	//! return true if web server is available
	bool	isWebServerAvailable( void );

	//! accept connection from skt manager
	RCODE	acceptRawLocalHttpConnection( VxSktBase * poSkt, VxNetIdent * poIdent, RcWebSkt ** ppoRetWebSkt );

	//! start skt threads for accepted web skt
	void	startWebSktThreads( RcWebSkt * poWebSkt );

	//! handle incoming data from socket
	RCODE	HandleWebData( RcWebSkt * poSkt );

	//! return true if more to parse
	bool	parseWebRxData( char * pDataBuf, 
							int iDataLen, 
							int& iRetDataUsed, 
							int& iHttpError,
							std::string& strRetFileName,
							int& iFileOffset,
							bool& bCloseConnection,
							EWbMyFiles * eFileType = NULL, 
							EHttpReqType * eHttpReqType = NULL, 
							std::string * strRetPwd = NULL );

	//! get real file name from website alias ( if has alias )
	RCODE	GetWebSiteRealFileName(	std::string& strWebFileName,	// web file name
									EWbMyFiles& peRetFileType );	// My shared file type
#ifdef USE_WEB_FILESHARE
	//! get build website progress
	virtual int GetBuildProgress( void ) = 0;

	//! return true if password has been set or no password required
	BOOL	IsPasswordOk( U32 u32IpAddr, EWbMyFiles eFileType );

	//! verify the password is correct for the given file share type
	BOOL	VerifyPwd( U32 u32IpAddr, EWbMyFiles eFileType, const char * pPwd );

	//! called once per second for authorization timeouts
	void	WebServerOncePerSecond( void );
#endif // USE_WEB_FILESHARE

	RCODE	sentWebServerData(	RcWebSkt *		poSkt,					// web socket
								const char *	pData,					// data to send
								int				iDataLen,				// length of data	
								BOOL			bDisconnectAfterSend,	// if true disconnect after data is sent
								int				iSendTimeoutSeconds );	// timeout attempt to send

	bool isExecuteableFile( std::string& strWebFileName );
};
